package ddz.logic.game;

import ch.qos.logback.classic.Logger;
import com.google.protobuf.InvalidProtocolBufferException;
import com.kaka.notice.Command;
import com.kaka.notice.Message;
import com.kaka.notice.annotation.Handler;
import com.kaka.util.MathUtils;
import ddz.constants.OpCode;
import ddz.core.*;
import ddz.db.dao.TableDao;
import ddz.net.ProtocolMessage;
import ddz.protos.*;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

/**
 * 自动处理加倍、出牌、过牌操作
 *
 * @author zkpursuit
 */
@Handler(cmd = OpCode.timer_auto_play, type = String.class)
public class TimerAutoHandler extends Command {

    private static final Logger logger = (Logger) LoggerFactory.getLogger(TimerAutoHandler.class);

    @Override
    public void execute(Message message) {
        Map<String, Object> dataMap = (Map<String, Object>) message.getBody();
        long deskId = (long) dataMap.get("desk");
        Object param = dataMap.get("param");

        TableDao deskdao = this.retrieveProxy(TableDao.class);
        Table table = deskdao.getDesk(deskId);
        if (table.getState() == TableState.jia_bei) {
            //自动处理加倍
            int cmd = Integer.parseInt(OpCode.cmd_jiabei);
            List<byte[]> bytesList = (List<byte[]>) param;
            for (int i = 0; i < bytesList.size(); i++) {
                byte[] scShowOptsBytes = bytesList.get(i);
                GameOpts.ScShowOpts scShowOpts = null;
                try {
                    scShowOpts = GameOpts.ScShowOpts.parseFrom(scShowOptsBytes);
                } catch (InvalidProtocolBufferException e) {
                    e.printStackTrace();
                }
                if (scShowOpts != null && !table.isAlreadyJiabei(scShowOpts.getSeat())) {
                    Player player = table.getPlayerBySeatIndex(scShowOpts.getSeat());
                    int opt = OptType.buJiabei.getId();
                    if (player.getTimeoutCount() == TrusteeType.robot.getTimeoutCount()) {
                        List<Integer> optList = scShowOpts.getOptList();
                        if (optList.size() <= 1) {
                            opt = OptType.buJiabei.getId();
                        } else {
                            opt = optList.get(MathUtils.random(0, optList.size() - 1));
                        }
                    }
                    byte[] bytes = GameJiabei.CsJiabei.newBuilder()
                            .setOpt(opt)
                            .setToken(scShowOpts.getToken())
                            .build().toByteArray();
                    sendMessage(new ProtocolMessage(cmd, bytes, player.getUid()));
                }
            }
            return;
        }

        GameOpts.ScShowOpts paramData = null;
        if (param != null) {
            try {
                paramData = GameOpts.ScShowOpts.parseFrom((byte[]) param);
            } catch (InvalidProtocolBufferException e) {
                e.printStackTrace();
            }
        }

        if (paramData == null) {
            logger.error("自动处理：附带数据为空");
            return;
        }

        Player player = table.getPlayerBySeatIndex(paramData.getSeat());
        boolean firstTimeout = false;
        if (player.getTimeoutCount() < 2) {
            player.setTimeoutCount(player.getTimeoutCount() + 1);
            deskdao.insertOrUpdateDesk(table);
            if (player.getTimeoutCount() >= 2) {
                firstTimeout = true;
            }
        }

        List<Integer> optList = paramData.getOptList();
        if (table.getState() == TableState.qiang_dizhu) {
            //自动处理抢地主
            List<OptRecord> records = table.getRecords();
            boolean hasJiaoDizhu = false; //有人叫过地主就是抢地主了
            for (OptRecord or : records) {
                if (or.getOptType() == OptType.jiaodizhu) {
                    hasJiaoDizhu = true;
                    break;
                }
            }
            int opt = hasJiaoDizhu ? OptType.qiangdizhu.getId() : OptType.jiaodizhu.getId();
            if (player.getTimeoutCount() == TrusteeType.robot.getTimeoutCount()) {
                if (optList.size() > 1) {
                    if (MathUtils.isHitProbability(70, 100)) {
                        //机器人只有35%的概率抢地主
                        opt = hasJiaoDizhu ? OptType.qiangdizhu.getId() : OptType.jiaodizhu.getId();
                    } else {
                        opt = hasJiaoDizhu ? OptType.buqiangdizhu.getId() : OptType.bujiaodizhu.getId();
                    }
                } else {
                    //ShowOptsHandler中分析出来不适合叫地主
                    opt = hasJiaoDizhu ? OptType.buqiangdizhu.getId() : OptType.bujiaodizhu.getId();
                }
            } else {
                //真人玩家必抢
            }
            int cmd = Integer.parseInt(OpCode.cmd_qiangdizhu);
            byte[] bytes = GameDizhu.CsQiangDizhu.newBuilder()
                    .setOpt(opt)
                    .setToken(paramData.getToken())
                    .build().toByteArray();
            sendMessage(new ProtocolMessage(cmd, bytes, player.getUid()));
        } else if (table.getState() == TableState.playing) {
            if (optList.size() == 1 && optList.get(0) == OptType.pass.getId()) {
                //仅过牌
                int passCmd = Integer.parseInt(OpCode.cmd_pass);
                byte[] passDataBytes = GamePass.CsPass.newBuilder()
                        .setOpt(OptType.pass.getId())
                        .setToken(paramData.getToken())
                        .build().toByteArray();
                sendMessage(new ProtocolMessage(passCmd, passDataBytes, player.getUid()));
            } else {
                boolean chu = false;
                if (optList.size() == 1 && optList.get(0) == OptType.chu.getId()) {
                    // 无过牌的操作，证明是首轮出牌，必出
                    chu = true;
                } else {
                    // 有过牌和出牌操作
                    int dizhuSeatIndex = table.getDizhuSeatIndex();
                    boolean selfIsDizhu = (player.getSeatIndex() == dizhuSeatIndex); //操作方是否为地主
                    ChuRecord lastRecord = table.getLastChuRecord();
                    boolean prefIsDizhu = (lastRecord.getSeatIndex() == dizhuSeatIndex); //上家出牌方是否为地主
                    if (selfIsDizhu || prefIsDizhu) {
                        //自己是地主，必压
                        //上个出牌的玩家是地主，必压
                        chu = true;
                    }
                    if (player.getTimeoutCount() == TrusteeType.robot.getTimeoutCount()) {
                        //如果是机器人，有出则必出
                        chu = true;
                    }
                }
                if (chu) {
                    int chuCmd = Integer.parseInt(OpCode.cmd_chu_card);
                    GameChu.CsChu.Builder csChuBuilder = GameChu.CsChu.newBuilder();
                    csChuBuilder.setOpt(OptType.chu.getId())
                            .setToken(paramData.getToken());
                    if (paramData.getGroupCount() > 0) {
                        csChuBuilder.setCards(paramData.getGroup(0));
                    }
                    byte[] chuDataBytes = csChuBuilder.build().toByteArray();
                    sendMessage(new ProtocolMessage(chuCmd, chuDataBytes, player.getUid()));
                } else {
                    int passCmd = Integer.parseInt(OpCode.cmd_pass);
                    byte[] passDataBytes = GamePass.CsPass.newBuilder()
                            .setOpt(OptType.pass.getId())
                            .setToken(paramData.getToken())
                            .build().toByteArray();
                    sendMessage(new ProtocolMessage(passCmd, passDataBytes, player.getUid()));
                }
            }
        }

        if (firstTimeout) {
            int cmd = Integer.parseInt(OpCode.cmd_trusteeship);
            byte[] csTrusteeBytes = GameTuoguan.CsTrustee.newBuilder()
                    .setType(0)
                    .setToken(paramData.getToken())
                    .build().toByteArray();
            this.sendMessage(new ProtocolMessage(cmd, csTrusteeBytes, player.getUid()));
        }

    }
}
